﻿using Koala.Pro.CodeGenerator.UI.DatabaseModel.Schema;

namespace Koala.Pro.CodeGenerator.UI.Common
{
    public class FillTablesCommand : AbstractGUICommand
    {
        private readonly TreeView dbTreeView;

        private readonly DbInstanceInfo dbInstance;

        private string selectedDatabaseName;

        public FillTablesCommand(IWin32Window owner, DbInstanceInfo dbInstance, TreeView tablesTreeView, string selectedDatabaseName)
            : base(owner)
        {
            this.dbInstance = dbInstance;
            this.dbTreeView = tablesTreeView;
            this.selectedDatabaseName = selectedDatabaseName;
        }

        public override void Execute()
        {
            try
            {
                dbTreeView.Nodes.Clear();
                IDictionary<string, DatabaseInfo> databaseList = dbInstance.DatabaseList;
                dbTreeView.BeginUpdate();
                Cursor.Current = Cursors.WaitCursor;
                foreach (KeyValuePair<string, DatabaseInfo> item in databaseList)
                {
                    TreeNode dbNode = new TreeNode(item.Value.Name.Name.ToString(), 1, 1);
                    dbNode.Tag = "database";
                    dbNode.SelectedImageIndex = 0;
                    dbNode.ImageIndex = 0;

                    TreeNode tableNode = new TreeNode("Tables", 2, 2);
                    tableNode.Tag = "Tables";
                    tableNode.SelectedImageIndex = 4;
                    tableNode.ImageIndex = 4;
                    var tableList = item.Value.ListTables();
                    foreach (KeyValuePair<string, TableInfo> table in tableList)
                    {
                        TreeNode treeNode = new TreeNode(table.Value.Name.Name.ToString(), 3, 3);
                        treeNode.Tag = "table";
                        treeNode.SelectedImageIndex = 2;
                        treeNode.ImageIndex = 2;
                        tableNode.Nodes.Add(treeNode);
                    }
                    TreeNode viewNode = new TreeNode("Views", 2, 2);
                    viewNode.Tag = "Views";
                    viewNode.SelectedImageIndex = 4;
                    viewNode.ImageIndex = 4;
                    foreach (KeyValuePair<string, ViewInfo> view in item.Value.ViewList)
                    {
                        TreeNode treeNode = new TreeNode(view.Value.Name.Name.ToString(), 4, 4);
                        treeNode.Tag = "view";
                        treeNode.SelectedImageIndex = 3;
                        treeNode.ImageIndex = 3;
                        viewNode.Nodes.Add(treeNode);
                    }
                    TreeNode procedureNode = new TreeNode("Procedures", 2, 2);
                    procedureNode.Tag = "Procedures";
                    procedureNode.SelectedImageIndex = 4;
                    procedureNode.ImageIndex = 4;
                    foreach (KeyValuePair<string, ProcedureInfo> procedure in item.Value.ProcedureList)
                    {
                        TreeNode treeNode = new TreeNode(procedure.Value.Name.Name.ToString(), 5, 5);
                        treeNode.Tag = "procedure";
                        treeNode.SelectedImageIndex = 1;
                        treeNode.ImageIndex = 1;
                        procedureNode.Nodes.Add(treeNode);
                    }
                    dbNode.Nodes.AddRange([tableNode, viewNode, procedureNode]);
                    dbTreeView.Nodes.Add(dbNode);
                }
                Cursor.Current = Cursors.Default;
                dbTreeView.EndUpdate();
                dbTreeView.CollapseAll();
                foreach (TreeNode node in dbTreeView.Nodes)
                {
                    if (node.Text == selectedDatabaseName)
                    {
                        dbTreeView.SelectedNode = node;
                        node.Expand();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }
    }

    public abstract class AbstractGUICommand : IGUICommand, ICommand
    {
        private IWin32Window _owner;

        public IWin32Window Owner
        {
            get
            {
                return _owner;
            }
            set
            {
                _owner = value;
            }
        }

        public AbstractGUICommand(IWin32Window owner)
        {
            _owner = owner;
        }

        public abstract void Execute();
    }

    public interface IGUICommand : ICommand
    {
        IWin32Window Owner { get; set; }
    }

    public interface ICommand
    {
        void Execute();
    }
}
